<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>流程图</title> 
    <style>
        .flowc{
            --arrow-height: 50px;
            list-style: none;
            justify-content: center;
            overflow: hidden;
        }
        .root > .node::before{
            display: none;
        }
        .node{
            position: relative;
            background: lightsalmon;
            flex: auto;
            display: flex;
        }
        .nodein{
            background: #E2DEEE; 
            border-radius: 8px; 
            padding: 5px 10px;
            width: fit-content;
        }
        .node::before{
            content: '';
            position: absolute;
            background: var(--arrow-line);
        }
        .node:first-child:not(:only-child)::before{
            background: none;
        }
        .node:last-child:not(:only-child)::before{
            background: none;
        }
        .node:only-child::before{
            border: none !important;
        }
        .subs{
            list-style: none;
            padding: 0;
            display: flex;
            position: relative;
        }
        .subs::before{
            content: '';
            position: absolute;
            background: var(--arrow-line);
        }
        .flowc.ttb{
            --arrow-line: linear-gradient(#999, #999) 50% 0px/1px 100% no-repeat;
            .flow-sub {
                position: relative;
                left: 50%;
                overflow: hidden;
                border-left: 1px solid #999;
                padding: 20px 45px;
            }
            .flow-sub + .subs {
                margin-top: var(--arrow-height);
            }
            .node{
                flex-flow: column;
            }
            .nodein{
                margin: 0 auto;
            }
            .node::before{
                height: var(--arrow-height);
                width: 100%;
                left: 50%;
                top: 0;
                transform: translate(-50%, -100%);
                border-top: 1px solid #969696;
            }
            .node:first-child:not(:only-child)::before{
                width: 50%;
                left: 50%;
                transform: translate(0, -100%);
                border-left: 1px solid #969696;
                border-top-left-radius: 8px;
            }
            .node:last-child:not(:only-child)::before{
                width: 50%;
                left: 0;
                transform: translate(0, -100%);
                border-right: 1px solid #969696;
                border-top-right-radius: 8px;
            }
            .subs{
                margin-top: calc(var(--arrow-height) * 2);
            }
            .subs::before{
                height: var(--arrow-height);
                width: 100%;
                transform: translate(0, -200%);
            }
        }
        .flowc.ltr{
            --arrow-line: linear-gradient(#999, #999) 0 50%/100% 1px no-repeat;
            .flow-sub {
                overflow: hidden;
                padding: 0 45px;
                align-items: center;
                display: flex;
                background: linear-gradient(#999, #999) 0 50%/100% 1px no-repeat;
            }
            .flow-sub > .node{
                transform: translateY(-200%);
                padding: 0;
            }
            .flow-sub > .node::before{
                width: 100%;
                height: 150%;
                top: 100%;
                left: 0;
                border-left: 1px solid #969696;
                transform: translate(0,0);
            }
            .flow-sub + .subs {
                margin-left: var(--arrow-height);
            }
            .node{
                flex-flow: row;
                padding: 5px 0;
            }
            .nodein{
                margin: auto 0;
            }
            .node::before{
                width: var(--arrow-height);
                height: 100%;
                top: 50%;
                left: 0;
                border-left: 1px solid #969696;
                transform: translate(-100%, -50%);
            }
            .node:first-child:not(:only-child)::before{
                height: 50%;
                top: 50%;
                transform: translate(-100%, 0);
                border-top: 1px solid #969696;
                border-top-left-radius: 8px;
            }
            .node:last-child:not(:only-child)::before{
                height: 50%;
                bottom: 50%;
                transform: translate(-100%, 0);
                border-bottom: 1px solid #969696;
                border-bottom-left-radius: 8px;
                top: unset;
            }
            .subs{
                flex-flow: column;
                margin-left: calc(var(--arrow-height) * 2);
            }
            .subs::before{
                height: 100%;
                width: var(--arrow-height);
                transform: translate(-200%, 0);
            }
        } 
        .flow-sub + .subs::before {
            display: none;
        }
    </style>
</head>
<body>
    <div class="modec">
        <select id="selMode">
            <option value="ttb" selected>纵向</option>
            <option value="ltr">横向</option>
        </select>
        <button id="btn" type="button">切换方向</button>
    </div>
    <div id="orgc" class="orgc"></div>
    <ul class="flowc">
        <li class="node root">
            <div class="nodein">Is availble < min-content</div>
            <ul class="subs">
                <li class="node"><div class="nodein">Is availble < max-content</div></li>
                <li class="node"><div class="nodein">Use min-content</div></li>
                <li class="node"><div class="nodein">Use min-content</div></li>
            </ul>
        </li>
    </ul>
    <script>  
        buildOrg('orgc');

        let btn = document.querySelector('#btn');
        btn.addEventListener('click', onModeChange);

        function buildOrg(orgcId, dir='ttb'){
            let con = document.querySelector(`#${orgcId}`);
            let root = getData();
            let html = gen_tree(root, dir);
            con.innerHTML = `<ul class="flowc ${dir}">${html}</ul>`;
        }

        function gen_tree(childs, dir){
            var html = ''
            let subDirMap = {'ltr':'ttb','ttb':'ltr'};
            childs.forEach(el => {
                html+=`<li class="node">
                        <div class="linec"></div>
                        <div class="nodein">${el.name}</div>`;
                if(el.tags && el.tags.length){
                    let subFlows = el.tags.map(t => `<li class="node"><div class="nodein">${t.name}</div></li>`).join('');
                    let subDir = subDirMap[dir];
                    html += `<ul class="flow-sub flowc ${subDir}">${subFlows}</ul>`;
                }
                if (el.children && el.children.length) {
                    html += `<ul class="subs">` + gen_tree(el.children, dir) + `</ul>`;
                }
                html+= `</li>`
            })
            return html;
        }

        function getData(){
            let data = [{
                name: 'root node',
                tags: [{
                    name: "副总裁",
                    type: "tag"
                }],
                children: [
                    {
                        name: "1",
                        children: [{
                            name: "1-1"
                        }]
                    }, 
                    {
                        name: "2",
                        tags: [{
                            name: '2-3',
                            type: "tag"
                        }],
                        children: [
                            {
                                name: "2-1"
                            }, 
                            {
                                name: "2-2",
                                children: [
                                {
                                    name: "2-2-1"
                                }, {
                                    name: "3-1-1"
                                }, {
                                    name: "3-1-2"
                                }, {
                                    name: "3-1-1"
                                }, {
                                    name: "3-1-2"
                                }, {
                                    name: "3-1-1"
                                }, {
                                    name: "3-1-2"
                                }]
                            }
                        ]
                    }, 
                    {
                        name: "3",
                        children: [
                        {
                            name: "3-1",
                            tags: [{
                                name: "我特殊",
                                type: "tag"
                            }],
                            children: [{
                                name: "3-1-1"
                            }, 
                            {
                                name: "3-1-2"
                            }, 
                            {
                                name: "3-1-2"
                            }, 
                            {
                                name: "3-1-1"
                            }, 
                            {
                                name: "3-1-2"
                            }]
                        }]
                    }]
            }]
            return data;
        }

        function onModeChange(){
            let selMode = document.getElementById('selMode');
            try {
                let target = selMode.value == 'ttb' ? 'ltr' : 'ttb';
                selMode.value = target;

                let flowc = document.querySelector('.flowc');
                flowc.className = 'flowc ' + target;

                // flowc.classList.add(selMode.value);
                console.log('sss: ', selMode)
                // buildOrg('orgc', selMode.value);
            } 
            catch (e) {
                console.log('e: ', e)
            }
            
        }
    </script>
</body>
</html>